package com.ygqh.baby.service.impl;

import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.mapper.YgBargainMapper;
import com.ygqh.baby.model.BargainProductListModel;
import com.ygqh.baby.model.EditBargainDetailReq;
import com.ygqh.baby.model.EditBargainReq;
import com.ygqh.baby.model.ProductBargainData;
import com.ygqh.baby.po.YgBargain;
import com.ygqh.baby.po.YgBargainExample;
import com.ygqh.baby.po.YgProduct;
import com.ygqh.baby.service.YgBargainDetailService;
import com.ygqh.baby.service.YgBargainService;
import com.ygqh.baby.utils.PlatformUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class YgBargainServiceImpl implements YgBargainService {

    @Autowired
    private YgBargainMapper ygBargainMapper;
    @Autowired
    private YgBargainDetailService ygBargainDetailService;

    @Override
    public List<YgBargain> find() {
        YgBargainExample example = new YgBargainExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return ygBargainMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        YgBargainExample example = new YgBargainExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return ygBargainMapper.countByExample(example);
    }

    @Override
    public YgBargain findById(Long id) {
        return ygBargainMapper.selectByPrimaryKey(id);
    }

    @Override
    public int save(YgBargain ygBargain) {
        return ygBargainMapper.insertSelective(ygBargain);
    }

    @Override
    public int update(YgBargain ygBargain) {
        return ygBargainMapper.updateByPrimaryKeySelective(ygBargain);
    }

    @Override
    public ResultSet<YgBargain> search(QueryInfo queryInfo, String q, JobStatus jobStatus, Date startDate, Date endDate) {
        List<YgBargain> list = ygBargainMapper.selectSuper(queryInfo, q, jobStatus != null ? jobStatus.name() : null, startDate, endDate);
        int count = ygBargainMapper.countSuper(q, jobStatus != null ? jobStatus.name() : null, startDate, endDate);
        return new ResultSet<>(count, list);
    }

    @Override
    public int deleteSoft(Long[] ids) {
        Assert.notEmpty(ids);
        YgBargainExample example = new YgBargainExample();
        example.createCriteria().andIdIn(Arrays.asList(ids));
        YgBargain record = new YgBargain();
        record.setStatus(DataStatus.Delete);

        return ygBargainMapper.updateByExampleSelective(record, example);
    }

    @Override
    public int deleteSoft(Long id) {
        return this.deleteSoft(new Long[]{id});
    }

    @Override
    public int saveOrUpdate(YgBargain ygBargain) {
        int r;
        if (ygBargain.getId() != null) {
            r = this.update(ygBargain);
        } else {
            r = this.save(ygBargain);
        }
        return r;
    }

    @Override
    public List<YgProduct> findProductForBargain(QueryInfo queryInfo, String productName, Long groupId, Long bargainId) {
        return ygBargainMapper.selectProductForBargain(queryInfo, productName, groupId, bargainId);
    }

    @Override
    public Boolean existBargain(Long productId, Long bargainId) {
        return ygBargainMapper.existBargain(productId, bargainId);
    }

    @Override
    public YgBargain findBargainByProductId(Long productId, SalesPlatform salesPlatform) {
        String[] platformNos = PlatformUtil.getPlatformNos(salesPlatform);
        return ygBargainMapper.selectBargainByProductId(productId, platformNos);
    }

    @Override
    public List<BargainProductListModel> findBargainProductList(QueryInfo queryInfo, Long bargainId,
                                                                SalesPlatform salesPlatform) {

        String[] platformNos = PlatformUtil.getPlatformNos(salesPlatform);
        return ygBargainMapper.selectBargainProductList(queryInfo, bargainId, new Date(), platformNos);
    }

    @Override
    public List<YgBargain> findBargainList(PromotionStatus promotionStatus, SalesPlatform salesPlatform) {
        String[] platformNos = PlatformUtil.getPlatformNos(salesPlatform);
        return ygBargainMapper.findBargainList(promotionStatus.name(), new Date(), platformNos);
    }

    @Override
    public int editBargain(EditBargainReq editBargainReq) {
        vaildEditParam(editBargainReq);
        YgBargain bargain = new YgBargain();
        BeanUtils.copyProperties(editBargainReq, bargain);
        bargain.setGenerationMode(editBargainReq.getGenerationMode().name());
        if (editBargainReq.getId() == null) {
            bargain.setCreateTime(editBargainReq.getUpdateTime());
            bargain.setCreateBy(editBargainReq.getHandler());
        }
        bargain.setUpdateBy(editBargainReq.getHandler());
        bargain.setUpdateTime(editBargainReq.getUpdateTime());
        int i = this.saveOrUpdate(bargain);
        editBargainReq.getDetailList().forEach(d -> {
            d.setBargainId(bargain.getId());
            d.setUpdateTime(editBargainReq.getUpdateTime());
            d.setHandler(editBargainReq.getHandler());
        });
        ygBargainDetailService.editBargainDetail(editBargainReq.getDetailList());
        return i;
    }

    private void vaildEditParam(EditBargainReq editBargainReq) {
        Assert.notNull(editBargainReq, "editBargainReq can't be null ");
        Assert.notNull(editBargainReq.getPlatformNo(), "platformNo can't be null ");
        Assert.notNull(editBargainReq.getActiveName(), "activeName can't be null ");
        Assert.notNull(editBargainReq.getTargetPrice(), "targetPrice can't be null ");
        Assert.notNull(editBargainReq.getBuyCount(), "buyCount can't be null ");
        Assert.notNull(editBargainReq.getCountDown(), "countDown can't be null ");
        Assert.notNull(editBargainReq.getGenerationMode(), "generationMode can't be null ");
        Assert.notNull(editBargainReq.getStartDate(), "startDate can't be null ");
        Assert.notNull(editBargainReq.getEndDate(), "endDate can't be null ");
        if (BargainGenerationMode.Order.equals(editBargainReq.getGenerationMode())) {
            Assert.notNull(editBargainReq.getExpressPrice(), "expressPrice can't be null ");
        } else if (BargainGenerationMode.CardCoupon.equals(editBargainReq.getGenerationMode())) {
            Assert.notNull(editBargainReq.getCardCountDown(), "cardCountDown can't be null ");
        }

        Assert.notEmpty(editBargainReq.getDetailList());
        editBargainReq.getDetailList().forEach(d -> {
            Assert.notNull(d.getProductId(), "detailList.productId can't be null.");
//            Assert.notNull(d.getBargainId(), "detailList.bargainId can't be null.");
            Assert.notNull(d.getMaxCutCount(), "detailList.maxCutCount can't be null.");
            Assert.notNull(d.getMinCutCount(), "detailList.mixCutCount can't be null.");
            Assert.notNull(d.getRealStock(), "detailList.realStock can't be null.");
            Assert.notNull(d.getStockQuantity(), "detailList.stockQuantity can't be null.");
        });
        List<Long> productIdList = editBargainReq.getDetailList().stream().map(EditBargainDetailReq::getProductId).collect(Collectors.toList());
        List<Long> productIdsInOtherBargain = ygBargainDetailService.getProductIdsInOtherBargain(editBargainReq.getId(),
                productIdList, editBargainReq.getStartDate(), editBargainReq.getEndDate());
        Assert.isTrue(CollectionUtils.isEmpty(productIdsInOtherBargain), "该时间段存在重复商品活动，" + StringUtil.join(productIdsInOtherBargain, ",".charAt(0)));
        if (editBargainReq.getId() != null) {
            YgBargain bargain = ygBargainMapper.selectByPrimaryKey(editBargainReq.getId());
            if (JobStatus.Running.getTitle().equals(bargain.getBargainStatus())) {
                Assert.isTrue(bargain.getGenerationMode().equals(editBargainReq.getGenerationMode().name()), "砍价生成方式不可更改。");
            }
        }
    }

    @Override
    public ProductBargainData findProductBargainData(Long productId, Long bargainId, String platformNo) {
        String[] platformNos = PlatformUtil.getPlatformNos(platformNo);
        return ygBargainMapper.selectProductBargainData(productId, bargainId, platformNos);
    }

    @Override
    public ProductBargainData findProductBargainData(Long userBargainId) {
        return ygBargainMapper.selectProductBargainDataByUserBargainId(userBargainId);
    }


}
